\subsection{\Example{} \#5}
\label{win16_near_far_pointers}

\lstinputlisting[style=customc]{\CURPATH/ex5.c}

\lstinputlisting[style=customasmx86]{\CURPATH/ex5.lst}

\myindex{Intel!8086!\RU{Модель памяти}\EN{Memory model}}
\RU{Здесь мы можем увидеть разницу между указателями}
\EN{Here we see a difference between the so-called} \q{near} \RU{и указателями}\EN{pointers and the} \q{far} 
\RU{еще один ужасный артефакт сегментированной памяти 16-битного 8086}
\EN{pointers: another weird artifact of segmented memory in 16-bit 8086}.

\RU{Читайте больше об этом}\EN{You can read more about it here}: \myref{8086_memory_model}.

\RU{Указатели }\q{near} \RU{(\q{близкие}) это те которые указывают в пределах текущего сегмента}
\EN{pointers are those which point within the current data segment}.
\RU{Поэтому}\EN{Hence, the}\RU{, функция} \TT{string\_compare()} \RU{берет на вход только 2 16-битных
значения и работает с данными расположенными в сегменте, на который указывает \TT{DS}}\EN{function takes only
two 16-bit pointers, and accesses the data from the  segment that \TT{DS} points to} 
(\EN{The }\RU{инструкция}\TT{mov al, [bx]} \RU{на самом деле работает как}\EN{instruction actually works like} 
\TT{mov al, ds:[bx]}\EMDASH{}\TT{DS} \RU{используется здесь неявно}\EN{is implicit here}).

\RU{Указатели }\q{far} \RU{(далекие) могут указывать на данные в другом сегменте памяти}%
\EN{pointers are those which may point to data in another memory segment}.\\
\RU{Поэтому}\EN{Hence} \TT{string\_compare\_far()} \RU{берет на вход 16-битную пару как указатель, загружает старшую
часть в сегментный регистр \TT{ES} и обращается к данным через него}
\EN{takes the 16-bit pair as a pointer, loads the high part of it in the \TT{ES} segment register and accesses
the data through it}\\
(\TT{mov al, es:[bx]}).
\RU{Указатели }\q{far} \RU{также используются в моем win16-примере касательно}%
\EN{pointers are also used in my} \\
\TT{MessageBox()}\EN{ win16 example}: \myref{win16_messagebox}. 
\RU{Действительно, ядро Windows должно знать, из какого сегмента данных читать текстовые строки, так что ему нужна
полная информация}\EN{Indeed, the Windows kernel is not aware which data segment to use when accessing text strings,
so it need the complete information}.

\RU{Причина этой разница в том, что компактная программа вполне может обойтись одним сегментом данных размером 64 килобайта,
так что старшую часть указателя передавать не нужна (ведь она одинаковая везде)}
\EN{The reason for this distinction is that a compact program may use just one 64kb data segment, so it doesn't need
to pass the high part of the address, which is always the same}.
\RU{Б\`{о}льшие программы могут использовать несколько сегментов данных размером 64 килобайта,
так что нужно указывать каждый раз, в каком сегменте расположены данные}
\EN{A bigger program may use several 64kb data segments, so it needs to specify the segment of the data each time}.

\RU{То же касается и сегментов кода}\EN{It's the same story for code segments}.
\RU{Компактная программа может расположиться в пределах одного 64kb-сегмента, тогда
функции в ней будут вызываться инструкцией \TT{CALL NEAR}, 
а возвращаться управление используя \TT{RETN}.}
\EN{A compact program may have all executable code within one 64kb-segment, 
then all functions in it will be called using the \TT{CALL NEAR} instruction, 
and the code flow will be returned using \TT{RETN}.}
\RU{Но если сегментов кода несколько, тогда и адрес вызываемой функции будет задаваться парой, 
вызываться она будет используя
\TT{CALL FAR}, а возвращаться управление используя \TT{RETF}.}
\EN{But if there are several code segments, 
then the address of the function is to be specified by a pair,
it is to be called using the
\TT{CALL FAR} instruction, and the code flow is to be returned using \TT{RETF}.}

\RU{Это то что задается в компиляторе указывая}\EN{This is what is set in the compiler by specifying} \q{memory model}.

\RU{Компиляторы под MS-DOS и Win16 имели разные библиотеки под разные модели памяти: они отличались типами указателей для
кода и данных}\EN{The compilers targeting MS-DOS and Win16 have specific libraries for each memory model: they differ
by pointer types for code and data}.

